#include "cppeditor.h"
#include <QDebug>

CppEditor::CppEditor(QWidget *parent)
    : BaseEditor(parent)
    , m_cppLexer(nullptr)
    , m_cpp11Mode(true)
{
    setupLanguage();
    setupCodeCompletion();
}

CppEditor::~CppEditor()
{
    // m_cppLexer由基类管理，不需要手动删除
}

void CppEditor::setupLanguage()
{
    setupCppLexer();
    if (m_syntaxHighlightingEnabled) {
        setLexer(m_cppLexer);
    }
}

void CppEditor::setupCodeCompletion()
{
    setupCppAPIs();
    setupCppKeywords();
}

QStringList CppEditor::getKeywords() const
{
    QStringList allKeywords;
    allKeywords += getCppKeywords();
    allKeywords += m_customKeywords;
    return allKeywords;
}

LanguageType CppEditor::getLanguageType() const
{
    return LanguageType::CPP;
}

void CppEditor::checkSyntax()
{
    clearSyntaxErrors();

    QString text = getAllText();
    QStringList lines = text.split('\n');

    // 简单的语法检查示例
    for (int i = 0; i < lines.size(); ++i) {
        QString line = lines[i].trimmed();

        // 检查当前行的括号匹配
        int openBraces = line.count('{');
        int closeBraces = line.count('}');
        int openParens = line.count('(');
        int closeParens = line.count(')');

        if (openBraces != closeBraces) {
            annotate(i, "Brace mismatch", QsciScintilla::AnnotationStandard);
            emit syntaxErrorDetected(i, "Brace mismatch");
        }

        if (openParens != closeParens) {
            annotate(i, "Parenthesis mismatch", QsciScintilla::AnnotationStandard);
            emit syntaxErrorDetected(i, "Parenthesis mismatch");
        }

        // 检查分号
        if (line.endsWith('{') || line.endsWith('}') || line.isEmpty() ||
            line.startsWith("//") || line.startsWith("/*") || line.startsWith("#")) {
            continue;
        }

        if (!line.endsWith(';') && !line.endsWith(':') && !line.contains("if") &&
            !line.contains("else") && !line.contains("for") && !line.contains("while") &&
            !line.contains("switch") && !line.contains("case") && !line.contains("default")) {
            annotate(i, "Missing semicolon", QsciScintilla::AnnotationStandard);
            emit syntaxErrorDetected(i, "Missing semicolon");
        }
    }
}

void CppEditor::addCustomKeywords(const QStringList &keywords)
{
    m_customKeywords += keywords;
    if (m_apis) {
        for (const QString &keyword : keywords) {
            m_apis->add(keyword);
        }
        m_apis->prepare();
    }
}

void CppEditor::setStandardCompliance(bool cpp11)
{
    m_cpp11Mode = cpp11;
    setupCodeCompletion(); // 重新设置代码补全
}

void CppEditor::setupCppLexer()
{
    m_cppLexer = new QsciLexerCPP(this);
    m_lexer = m_cppLexer;

    // 设置C++语言特性，折叠
    m_cppLexer->setFoldAtElse(true);
    m_cppLexer->setFoldComments(true);
    m_cppLexer->setFoldCompact(false);
    m_cppLexer->setFoldPreprocessor(true);

    // 设置颜色主题
    m_cppLexer->setColor(QColor("#0000FF"), QsciLexerCPP::Keyword);           // 关键字 - 蓝色
    m_cppLexer->setColor(QColor("#008000"), QsciLexerCPP::Comment);           // 注释 - 绿色
    m_cppLexer->setColor(QColor("#008000"), QsciLexerCPP::CommentLine);       // 行注释 - 绿色
    m_cppLexer->setColor(QColor("#FF0000"), QsciLexerCPP::DoubleQuotedString); // 字符串 - 红色
    m_cppLexer->setColor(QColor("#FF0000"), QsciLexerCPP::SingleQuotedString); // 字符 - 红色
    m_cppLexer->setColor(QColor("#800080"), QsciLexerCPP::Number);            // 数字 - 紫色
    m_cppLexer->setColor(QColor("#808080"), QsciLexerCPP::Operator);          // 操作符 - 灰色
    m_cppLexer->setColor(QColor("#800080"), QsciLexerCPP::PreProcessor);      // 预处理 - 紫色
}

void CppEditor::setupCppAPIs()
{
    if (m_apis) {
        delete m_apis;
    }

    m_apis = new QsciAPIs(m_cppLexer);

    // 添加C++关键字
    QStringList keywords = getCppKeywords();
    for (const QString &keyword : keywords) {
        m_apis->add(keyword);
    }

    // 添加C++类型
    QStringList types = getCppTypes();
    for (const QString &type : types) {
        m_apis->add(type);
    }

    // 添加C++函数
    QStringList functions = getCppFunctions();
    for (const QString &function : functions) {
        m_apis->add(function);
    }

    // 添加自定义关键字
    for (const QString &keyword : m_customKeywords) {
        m_apis->add(keyword);
    }

    m_apis->prepare();
}

void CppEditor::setupCppKeywords()
{
    // 设置词法分析器的关键字
    //m_cppLexer->setKeywords(0, getCppKeywords().join(" "));
    //m_cppLexer->setKeywords(1, getCppTypes().join(" "));
}

QStringList CppEditor::getCppKeywords() const
{
    QStringList keywords;
    keywords << "auto" << "break" << "case" << "char" << "const" << "continue"
             << "default" << "do" << "double" << "else" << "enum" << "extern"
             << "float" << "for" << "goto" << "if" << "int" << "long" << "register"
             << "return" << "short" << "signed" << "sizeof" << "static" << "struct"
             << "switch" << "typedef" << "union" << "unsigned" << "void" << "volatile"
             << "while" << "class" << "private" << "protected" << "public" << "friend"
             << "inline" << "template" << "virtual" << "operator" << "new" << "delete"
             << "this" << "namespace" << "using" << "try" << "catch" << "throw"
             << "const_cast" << "dynamic_cast" << "reinterpret_cast" << "static_cast"
             << "typeid" << "typename" << "explicit" << "mutable" << "export";

    if (m_cpp11Mode) {
        keywords << "nullptr" << "constexpr" << "decltype" << "override" << "final"
                 << "noexcept" << "static_assert" << "thread_local" << "alignof"
                 << "alignas";
    }

    return keywords;
}

QStringList CppEditor::getCppTypes() const
{
    QStringList types;
    types << "bool" << "char" << "wchar_t" << "char16_t" << "char32_t"
          << "short" << "int" << "long" << "signed" << "unsigned"
          << "float" << "double" << "long double" << "void"
          << "string" << "vector" << "list" << "map" << "set" << "queue"
          << "stack" << "deque" << "array" << "unordered_map" << "unordered_set"
          << "shared_ptr" << "unique_ptr" << "weak_ptr";

    if (m_cpp11Mode) {
        types << "auto" << "decltype";
    }

    return types;
}

QStringList CppEditor::getCppFunctions() const
{
    QStringList functions;
    functions << "printf" << "scanf" << "cout" << "cin" << "endl"
              << "malloc" << "free" << "new" << "delete" << "sizeof"
              << "strlen" << "strcpy" << "strcmp" << "strcat" << "memcpy"
              << "memset" << "abs" << "sqrt" << "pow" << "sin" << "cos"
              << "tan" << "log" << "exp" << "floor" << "ceil" << "rand"
              << "srand" << "time" << "exit" << "system" << "getchar"
              << "putchar" << "fopen" << "fclose" << "fread" << "fwrite"
              << "fprintf" << "fscanf" << "fgets" << "fputs";

    return functions;
}
